package com.taxi.driver.module.amap;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.MapView;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.LatLngBounds;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.route.DrivePath;
import com.amap.api.services.route.DriveRouteResult;
import com.qianxx.utils.RxUtil;
import com.taxi.driver.R;
import com.taxi.driver.common.BaseFragment;
import com.taxi.driver.config.DriverType;
import com.taxi.driver.config.TimeType;
import com.taxi.driver.event.MapEvent;
import com.taxi.driver.module.amap.assist.DrivingRouteOverlay;
import com.taxi.driver.module.amap.assist.MapUtils;
import com.taxi.driver.module.amap.dagger.AMapModule;
import com.taxi.driver.module.amap.dagger.DaggerAMapComponent;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.concurrent.TimeUnit;

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.ButterKnife;
import rx.Observable;

/**
 * 功能描述：用于"路径规划"的地图片段
 * <p>
 * todo 8.22 地图改造
 */
public class AMapFragment extends BaseFragment implements AMapContract.View {

    public static AMapFragment newInstance() {
        return new AMapFragment();
    }

    private final static int DefaultPadding = 80; //地图绘制点或悬浮物，距离边的距离（单位：像素）

    @BindView(R.id.map_view)
    MapView mMapView;

    private int top;
    private int bottom;
    private int typeTime = TimeType.APPOINTMENT;//订单类型
    private int driverType = DriverType.SPECIAL;//司机类型
    private boolean mIsMapLoaded;

    private AMap mAMap; //地图对象
    private LatLonPoint mStartPoint;//起点
    private LatLonPoint mEndPoint;//终点
    private DriveRouteResult mDriveRouteResult; //路径规划对象

    @Inject
    AMapPresenter mAMapPresenter;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mView = inflater.inflate(R.layout.fragment_amap, container, false);
        ButterKnife.bind(this, mView);

        initMap(savedInstanceState);
        EventBus.getDefault().register(this);
        return mView;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        DaggerAMapComponent.builder()
                .appComponent(getAppComponent())
                .aMapModule(new AMapModule(this))
                .build()
                .inject(this);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMapEvent(MapEvent mapEvent) {
        switch (mapEvent.type) {
            case MapEvent.MAP_CACULATE_ROUTE: //路径规划
                if (mapEvent.obj1 == null || mapEvent.obj2 == null) {
                    return;
                }
                LatLng origin = (LatLng) mapEvent.obj1;
                LatLng dest = (LatLng) mapEvent.obj2;
                typeTime = (int) mapEvent.obj3;
                driverType = (int) mapEvent.obj4;
                mStartPoint = new LatLonPoint(origin.latitude, origin.longitude);
                mEndPoint = new LatLonPoint(dest.latitude, dest.longitude);

                calculateDriverRoute(); //规划路径
                break;
            case MapEvent.MAP_PADDING://设置top和bottom的边距
                if (mapEvent.obj1 == null || mapEvent.obj2 == null) {
                    return;
                }
                top = (int) mapEvent.obj1;
                bottom = (int) mapEvent.obj2;
                addToMap(); //刷新地图显示
                break;
            case MapEvent.MAP_POINT://显示单个点
                if (mapEvent.obj1 == null) return;
                pointAddToMapCenter((LatLng) mapEvent.obj1); //显示起点
                break;
            case MapEvent.MAP_ORIGN_DEST://显示起点和终点
                addOriginAndDest((LatLng) mapEvent.obj1, (LatLng) mapEvent.obj2, (int) mapEvent.obj3);//显示起点和终点
                break;
            case MapEvent.MAP_LOCATION://定位
                LatLngBounds.Builder boundsBuilder = LatLngBounds.builder();
                boundsBuilder.include((LatLng) mapEvent.obj1);
                boundsBuilder.include((LatLng) mapEvent.obj2);
                mMapView.getMap().animateCamera(CameraUpdateFactory.newLatLngBoundsRect(boundsBuilder.build(),
                        DefaultPadding, //左边距
                        DefaultPadding, //右边距
                        DefaultPadding, //上边距
                        DefaultPadding), //下边距
                        500, null);
                break;
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        EventBus.getDefault().unregister(this);
    }

    //初始化地图
    private void initMap(Bundle savedInstanceState) {
        mMapView.onCreate(savedInstanceState); //此方法必须重写，才能正常显示
        if (mAMap == null) {
            mAMap = mMapView.getMap(); //获取地图对象
        }
        mAMap.setOnMapLoadedListener(() -> { //监听地图是否加载完成
            mIsMapLoaded = true;
            addToMap();
        });
        mAMap.getUiSettings().setZoomControlsEnabled(false); //隐藏缩放按键
    }

    /**
     * 规划路径
     */
    public void calculateDriverRoute() {
        if (mStartPoint == null || mEndPoint == null)
            return;

        mAMapPresenter.routeSearch(mStartPoint, mEndPoint);
    }

    /**
     * 将路径添加到地图上
     */
    private void addToMap() {
        if (!mIsMapLoaded || mDriveRouteResult == null) return;
        mAMap.clear(); // 清理地图上的所有覆盖物
        LatLng origin = new LatLng(mDriveRouteResult.getStartPos().getLatitude(), mDriveRouteResult.getStartPos().getLongitude());
        LatLng dest = new LatLng(mDriveRouteResult.getTargetPos().getLatitude(), mDriveRouteResult.getTargetPos().getLongitude());
        Bitmap originBitmap = null;
        Bitmap destBitmap = null;

        // 订单类型是即时单或日租/半日租，起点显示对应类型的小车
        if (typeTime == TimeType.REALTIME || typeTime == TimeType.DAILY_RENT || typeTime == TimeType.HALF_DAY_RENT) {

                originBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.map_icon_car);

            destBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.public_pic_qidian);
        } else {
            originBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.public_pic_qidian);
            destBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.public_pic_zhongdian);
        }

        //添加起点
        mAMap.addMarker(new MarkerOptions()
                .position(origin)
                .title("起点")
                .icon(BitmapDescriptorFactory.fromBitmap(originBitmap)));

        //添加终点
        mAMap.addMarker(new MarkerOptions()
                .position(dest)
                .title("终点")
                .icon(BitmapDescriptorFactory.fromBitmap(destBitmap)));

        final DrivePath drivePath = mDriveRouteResult.getPaths().get(0);
        DrivingRouteOverlay drivingRouteOverlay = new DrivingRouteOverlay(
                getContext(), mAMap, drivePath,
                mDriveRouteResult.getStartPos(),
                mDriveRouteResult.getTargetPos(), null);
        drivingRouteOverlay.setNodeIconVisibility(false);//设置节点marker是否显示
        drivingRouteOverlay.setIsColorfulline(false);//是否用颜色展示交通拥堵情况，默认true
        drivingRouteOverlay.removeFromMap();
        drivingRouteOverlay.addToMap();
        LatLngBounds.Builder boundsBuilder = LatLngBounds.builder();
        boundsBuilder.include(new LatLng(mStartPoint.getLatitude(), mStartPoint.getLongitude()));
        boundsBuilder.include(new LatLng(mEndPoint.getLatitude(), mEndPoint.getLongitude()));
        mMapView.getMap().animateCamera(CameraUpdateFactory.newLatLngBoundsRect(boundsBuilder.build(),
                DefaultPadding, //左边距
                DefaultPadding, //右边距
                top + DefaultPadding, //上边距
                bottom + DefaultPadding), //下边距
                200, null);
    }

    /**
     * 将点添加到地图上
     */
    private void pointAddToMapCenter(LatLng latLng) {
        if (latLng == null) return;
        MapUtils.setOriginMarker(getContext(), latLng, mAMap);
        mAMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15), 800, null);
    }

    /**
     * 添加起点和终点
     *
     * @param origin
     * @param dest
     */
    private void addOriginAndDest(LatLng origin, LatLng dest, int margin) {
        mAMap.clear();

        Observable.timer(800, TimeUnit.MILLISECONDS)
                .compose(RxUtil.applySchedulers())
                .subscribe(aLong -> {
                    if (origin == null) return;
                    MapUtils.setOriginMarker(getContext(), origin, mAMap);
                    if (dest == null) return;
                    MapUtils.setEndMarker(getContext(), dest, mAMap);
                    MapUtils.moveTovisibleArea(mAMap, origin, dest,
                            DefaultPadding, //左边距
                            DefaultPadding, //右边距
                            DefaultPadding, //上边距
                            margin + DefaultPadding * 3);//下边距
                });
    }

    @Override
    public void routeShow(DriveRouteResult result) {
        mDriveRouteResult = result;
        addToMap();
    }
}